package 异常处理;

//import org.junit.Test;
//import org.slf4j.Logger;

//public 
//class Hello {
//    static Logger logger = LogManager.getLogger(使用commonslogging.class.getName());
//    @SuppressWarnings("deprecation")
//	public boolean hello() {
//        logger.entry();   //trace级别的信息，单独列出来是希望你在某个方法或者程序逻辑开始的时候调用，和logger.trace("entry")基本一个意思
//        logger.error("Did it again!");   //error级别的信息，参数就是你输出的信息
//        logger.info("我是info信息");    //info级别的信息
//        logger.debug("我是debug信息");
//        logger.warn("我是warn信息");
//        logger.fatal("我是fatal信息");
//        logger.log(Level.DEBUG, "我是debug信息");   //这个就是制定Level类型的调用：谁闲着没事调用这个，也不一定哦！
//        logger.exit();    //和entry()对应的结束方法，和logger.trace("exit");一个意思
//        return false;
//    }
//}

//【构建路径】->【配置构建路径】->【库】->【类路径】->【添加外部 JAR<(X)】或(maven下)
//pom.xml添加：
//	<dependency>
// 	<groupId>commons-logging</groupId>  
//		 <artifactId>commons-logging</artifactId>  
//	 	<version>1.2</version>  
// </dependency>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;

public class 使用commonslogging {
	//private static Log logger = LogFactory.getLog(使用commonslogging.class);
	private static Logger logger1 = Logger.getLogger(使用commonslogging.class);

	public static void main(String[] args) {
		logger1.setLevel(Level.ALL);
		//logger.debug("调试信息.....");
		//logger.info("输出信息......");
		//logger.error("错误信息.......");
		//logger.warn("警告信息.....");
		//logger.trace("跟踪信息.....");
		//logger.fatal("致命信息.......");
		//System.out.println("Hello World!");
		
		logger1.debug("调试信息.....");
		logger1.info("输出信息......");
		logger1.error("错误信息.......");
		logger1.warn("警告信息.....");
		logger1.trace("跟踪信息.....");
		logger1.fatal("致命信息.......");
		System.out.println("Hello World!");
	}
}
/*
class HelloWorld {
    private static final Logger logger = LogManager.getLogger("HelloWorld");
    public static void main(String[] args) {
        logger.info("Hello, World!");
    }
}

public class 使用commonslogging {
    private static Logger logger = LogManager.getLogger(使用commonslogging.class.getName());
    public static void main(String[] args) {
        logger.trace("开始程序.");
        HelloWorld hello= new HelloWorld();
//        for (int i = 0; i < 10000;i++){
//            if (!hello.hello()) {
                logger.error("hello");
//            }
//        }
        logger.trace("退出程序.");
    }
}
*/

//运行上述代码，肯定会得到编译错误，类似error: package org.apache.commons.logging does not exist
//（找不到org.apache.commons.logging这个包）。因为Commons Logging是一个第三方提供的库，所以，必须先把它下载下来。
//下载后，解压，找到commons-logging-1.2.jar这个文件，再把Java源码Main.java放到一个目录下，例如work目录：

//work
//│
//├─ commons-logging-1.2.jar
//│
//└─ Main.java
//然后用javac编译Main.java，编译的时候要指定classpath，不然编译器找不到我们引用的org.apache.commons.logging包。编译命令如下：
//
//javac -cp commons-logging-1.2.jar Main.java
//如果编译成功，那么当前目录下就会多出一个Main.class文件：
//
//work
//│
//├─ commons-logging-1.2.jar
//│
//├─ Main.java
//│
//└─ Main.class
//现在可以执行这个Main.class，使用java命令，也必须指定classpath，命令如下：
//
//java -cp .;commons-logging-1.2.jar Main
//注意到传入的classpath有两部分：一个是.，一个是commons-logging-1.2.jar，用;分割。.表示当前目录，如果没有这个.，JVM不会在当前目录搜索Main.class，就会报错。
//
//如果在Linux或macOS下运行，注意classpath的分隔符不是;，而是:：
//
//java -cp .:commons-logging-1.2.jar Main
//运行结果如下：
//
//Mar 02, 2019 7:15:31 PM Main main
//INFO: start...
//Mar 02, 2019 7:15:31 PM Main main
//WARNING: end.
//Commons Logging定义了6个日志级别：
//
//FATAL
//ERROR
//WARNING
//INFO
//DEBUG
//TRACE
//默认级别是INFO。
//
//使用Commons Logging时，如果在静态方法中引用Log，通常直接定义一个静态类型变量：

// 在静态方法中引用Log:
//public class Main {
//    static final Log log = LogFactory.getLog(Main.class);
//
//    static void foo() {
//        log.info("foo");
//    }
//}
//在实例方法中引用Log，通常定义一个实例变量：
//
//// 在实例方法中引用Log:
//public class Person {
//    protected final Log log = LogFactory.getLog(getClass());
//
//    void foo() {
//        log.info("foo");
//    }
//}
//注意到实例变量log的获取方式是LogFactory.getLog(getClass())，虽然也可以用LogFactory.getLog(Person.class)，
//但是前一种方式有个非常大的好处，就是子类可以直接使用该log实例。例如：
//
//// 在子类中使用父类实例化的log:
//public class Student extends Person {
//    void bar() {
//        log.info("bar");
//    }
//}
//由于Java类的动态特性，子类获取的log字段实际上相当于LogFactory.getLog(Student.class)，但却是从父类继承而来，并且无需改动代码。
//
//此外，Commons Logging的日志方法，例如info()，除了标准的info(String)外，还提供了一个非常有用的重载方法：info(String, Throwable)，这使得记录异常更加简单：
//
//try {
//    ...
//} catch (Exception e) {
//    log.error("got exception!", e);
//}

//import org.apache.commons.logging.Log;
//import org.apache.commons.logging.LogFactory;
//import org.apache.commons.logging.*;
//import java.io.UnsupportedEncodingException;
//import org.apache.log4j.Logger;

//public class 使用commonslogging {
////	static final Log log = LogFactory.getLog(使用commonslogging.class);
//
//	public static void main(String[] args) {
//		// TODO Auto-generated method stub
//		Log log = LogFactory.getLog(使用commonslogging.class);
//		log.info("start...");
//		try {
//			"".getBytes("invalidCharsetName");
//		}catch(UnsupportedEncodingException e) {
//			// TODO: 使用log.error(String, Throwable)打印异常
//			log.error(e.toString(),e);
//		}
//		log.warn("end.");
//	}
//}
/*
commons-logging的目的是为“所有的Java日志实现”提供一个统一的接口，使项目与日志实现工具解耦。

一、为什么要使用commons-logging+log4j？
commons-logging和log4j都是Apache下的开源项目。commons-logging的目的是为“所有的Java日志实现”提供一个统一的接口，使项目与日志实现工具解耦，它自身的
日志功能比较弱（只有一个简单的 SimpleLog），所以一般不会单独使用它。
Log4j的功能非常强大，是目前最主流的java日志工具。结合使用两者可以避免使项目与log4j紧密耦合，用户可以轻松切换到其他日志工具，同时又可以使用log4j的强大功能。

二、commons-logging如何自动选择适当的日志实现工具？
我们在使用commons-logging+日志实现工具时，我们的代码只需要和commons-logging打交道，由commons-logging去选择适当的日志实现工具。
这里我们看一下commons-logging是如何去选择实现工具的：

F:\eclipse-workspace\jar\comm-logging\commons-logging-1.2.jar
	org.apache.commons.logging
		org.apache.commons.logging.impl
			org.apache.commons.logging.impl.AvalonLogger.class
			org.apache.commons.logging.impl.Jdk13LumberjackLogger.class
			org.apache.commons.logging.impl.Jdk14Logger.class  //使用JUL。
			org.apache.commons.logging.impl.Log4JLogger.class  //使用Log4J。
			org.apache.commons.logging.impl.LogFactoryImpl.class
			org.apache.commons.logging.impl.LogKitLogger.class //使用 avalon-Logkit。
			org.apache.commons.logging.impl.NoOpLog.class //common-logging自带日志实现类。它实现了Log接口。 其输出日志的方法中不进行任何操作
			org.apache.commons.logging.impl.ServletContextCleaner.class
			org.apache.commons.logging.impl.SimpleLog.class//common-logging自带日志实现类。它实现了Log接口，把日志消息都输出到系统错误流System.err 中。
			org.apache.commons.logging.impl.WeakHashtable.class
		org.apache.commons.logging.Log.class
		org.apache.commons.logging.LogConfigurationException.class
		org.apache.commons.logging.LogFactory.class
		org.apache.commons.logging.LogSource.class
	/META-INF

●首先
在classpath下寻找自己的配置文件commons-logging.properties，如果找到，则使用其中定义的Log实现类：
org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog; //使用commons-logging的SimpleLog
或：
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger;//选择使用log4j
或：
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Jdk14Logger; //选择jdk的logger

注：而当我们在common-logging.properties配置使用的是SimpleLog日志实现，该日志实现默认日志级别是info，所以才会出现简单实例中的输出结果，如何更改SimpleLog
的日志级别？
创建simplelog.properties配置文件，放到classpath下，如果是maven则放到src/main/resource目录下,配置内容参考：
     org.apache.commons.logging.simplelog.defaultlog=TRACE
配置后结果输出如下（bingo）：
[TRACE] CommonsTest - TRACE...
[DEBUG] CommonsTest - DEBUG ...
[INFO] CommonsTest - INFO ...
[ERROR] CommonsTest - ERROR ...
[WARN] CommonsTest - WARN...

●如果找不到commons-logging.properties文件，则在查找是否已定义系统环境变量org.apache.commons.logging.Log，找到则使用其定义的Log实现类

●否则
查看classpath中是否有Log4j的包，如果发现，则自动使用Log4j作为日志实现类。

●否则
使用JDK自身的日志实现类（JDK1.4以后才有日志实现类）。

●否则
使用commons-logging自己提供的一个简单的日志实现类SimpleLog。
可见，commons-logging总是能找到一个日志实现类，并且尽可能找到一个最合适的日志实现类。上述步骤当LogFactory成功找到一个日志实现之后就会停止
为了简化配置，我们可以不使用commons-logging的配置文件，也不设置commons-logging相关的环境变量，只需将log4j的包放入classpath就可以了，这样就可以完
成commons-logging与log4j的结合。如果以后不想使用log4j，只需将log4j的包 从classpath中移除就可以了。

【common-logging+log4j应用】
log4j功能强大，为了解耦和减少依赖，大部分的项目都会使用common-logging+log4j的组合进行开发，使用起来也是十分的简单：

①引入log4j的jar包，最新jar包从官方网站http://logging.apache.org/log4j/1.2/download.html进行下载，下载后将jar包放到lib中引入项目即可。

如果是maven项目在pom文件中添加依赖如下：

<dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
</dependency>
②在common-logging.properties文件,将log指向log4j

org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
③创建log4j.properties文件，并将文件放在classpath下，如果是maven则放在source/main/resource目录下，简单配置如下：

#配置rootLogger
log4j.rootLogger=all,appender1

#配置第一个appender
log4j.appender.appender1=org.apache.log4j.FileAppender
#配置文件输出样式
log4j.appender.appender1.layout = org.apache.log4j.PatternLayout
log4j.appender.appender1.layout.ConversionPattern = [%-5p][%-22d{yyyy/MM/dd HH:mm:ssS}][%l]%n%m%n
#指定仅记录ERROR以上级别的日志
log4j.appender.appender1.Threshold = ERROR
log4j.appender.appender1.ImmediateFlush = TRUE
#指定将日志累加到日志文件末尾
log4j.appender.appender1.Append = TRUE
#指定日志文件
log4j.appender.appender1.File = ./Common-logging-Modle/log/error.log
log4j.appender.appender1.Encoding = UTF-8
④运行代码不变，结果如下：

error.log

[ERROR][2019/01/31 17:56:13569][com.log.CommonsTest.main(CommonsTest.java:16)]
ERROR ...


三、如何在代码中输出日志？

●导入所需commons-logging的类
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

●在自己的类中定义一个org.apache.commons.logging.Log类的私有静态类变量
private static Log log = LogFactory.getLog(ClassName.class);

●使用静态类变量输出日志信息
为了方便的控制日志输出，把日志分成了不同的级别，从低到高分别是调试，信息，警告，错误，致命错误。这样我们可以通过log4j的配置决定只输出某个级别以上的日志。例如，
在开发时我们将debug(调试)及以上的日志全部输出，而在项目正常运行时，设置为只输出warn(警告)及以上的日志。
//输出各级别的日志信息
log.debug("debug"); //调试
log.info("information"); //信息
log.warn("warning"); //警告
log.error("error"); //错误
log.fatal("fatal"); //致命错误

将commons-logging和Log4j的jar包都放置到classpath下，同时也将Log4j的配置文件放到classpath中，两者就可以很好的合作，实现如下：

package com.doctorcom.model;   
  import org.apache.commons.logging.Log;       
  public class LogFactorySupport {          
      public Log getLog(){   
          Log log = org.apache.commons.logging.LogFactory.getLog(LogFactorySupport.class);   
          log.info("");   
          log.debug("");   
        }       
    } 

Log4j配置内容主要是依据配置文件log4j.properties：

#指定根Logger，及日志输出级别
#大于等于该级别的日志将被输出（ ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF），设为OFF可以关闭日志   
log4j.rootLogger=DEBUG, A1,A2   
#指定log输出目的,这里设为输出日志到指定目录的文件my.log中   
log4j.appender.A1=org.apache.log4j.FileAppender   
log4j.appender.A1.File=\\logs\\my.log   #当前根目录下
#指定日志信息的格式   
log4j.appender.A1.layout=org.apache.log4j.PatternLayout    
log4j.appender.A1.layout.ConversionPattern=%r %d{yyyy-MM-dd HH:mm:ss} %c %p -%m%n   
#把A2输出到控制台   
log4j.appender.A2=org.apache.log4j.ConsoleAppender   
log4j.appender.A2.layout=org.apache.log4j.SimpleLayout    
#还可以单独指定输出某个包的日志级别   
#log4j.logger.com.study.HelloLog4j=INFO

注：log4j在Level类中定义了7个等级，关系如下：
   Level.ALL < Level.DEBUG < Level.INFO < Level.WARN < Level.ERROR < Level.FATAL < Level.OFF

slf4j
slf4j全称是：simple logging facade for java，可以理解为简单日记门面。准确的说，slf4j并不是一种具体的日志系统，而是一个用户日志系统的facade，它允许用户
在部署最终应用时方便的变更其日志系统。
slf4j最吸引我的地方是：占位符(place holder)的使用。占位符在代码中表示为“{}”的特性。占位符是一个非常类似于在String的format()方法中的%s，因为它会在运行时
被某个提供的实际字符串所替换。这不仅降低了代码中字符串连接次数，而且还节省了新建的String对象。

下面是在Log4j中使用的方案，但这样做降低了代码可读性因为增加了不必要的繁琐重复代码：

if (logger.isDebugEnabled()) {
    logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
}
但是如果你使用slf4j的话，你可以得到在极简洁的格式的结果，就像以下展示的一样：

logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);
*/

/*
commons-logging和Log4j 日志管理 (zz)

为什么同时使用commons-logging和Log4j?为什么不仅使用其中之一？
Commons-loggin的目的是为“所有的Java日志实现”提供一个统一的接口，它自身的日志功能平常弱（只有一个简单的SimpleLog?），所以一般不会单独使用它。

Log4j的功能非常全面强大，是目前的首选。我发现几乎所有的Java开源项目都会用到Log4j，但我同时发现，所有用到Log4j的项目一般也同时会用到commons-loggin。我想，大
家都不希望自己的项目与Log4j绑定的太紧密吧。另外一个我能想到的“同时使用commons-logging和Log4j”的原因是，简化使用和配置。

   强调一点，“同时使用commons-logging和Log4j”，与“单独使用Log4j”相比，并不会带来更大的学习、配置和维护成本，反而更加简化了我们的工作。我想这也是为什么“所有
用到Log4j的项目一般也同时会用到commons-loggin”的原因之一吧。

Commons-logging能帮我们做什么？
-提供一个统一的日志接口，简单了操作，同时避免项目与某个日志实现系统紧密a耦合 
-很贴心的帮我们自动选择适当的日志实现系统（这一点非常好！） 
-它甚至不需要配置

这里看一下它怎么“‘很贴心的’帮我们‘自动选择’‘适当的’日志实现系统”： 
1) 首先在classpath下寻找自己的配置文件commons-logging.properties，如果找到，则使用其中定义的Log实现类； 
2) 如果找不到commons-logging.properties文件，则在查找是否已定义系统环境变量org.apache.commons.logging.Log，找到则使用其定义的Log实现类； 
3) 否则，查看classpath中是否有Log4j的包，如果发现，则自动使用Log4j作为日志实现类； 
4) 否则，使用JDK自身的日志实现类（JDK1.4以后才有日志实现类）； 
5) 否则，使用commons-logging自己提供的一个简单的日志实现类SimpleLog； 
（以上顺序不保证完全准确，请参考官方文档）

可见，commons-logging总是能找到一个日志实现类，并且尽可能找到一个“最合适”的日志实现类。我说它“很贴心”实际上是因为：
1、可以不需要配置文件；
2、自动判断有没有Log4j包，有则自动使用之；
3、最悲观的情况下也总能保证提供一个日志实现（SimpleLog）。 
  可以看到，commons-logging对编程者和Log4j都非常友好。

  为了简化配置commons-logging，一般不使用commons-logging的配置文件，也不设置与commons-logging相关的系统环境变量，而只需将Log4j的Jar包放置
到classpash中就可以了。这样就很简单地完成了commons-logging与Log4j的融合。如果不想用Log4j了怎么办？只需将classpath中的Log4j的Jar包删除即可。
就这么简单！

代码应该怎么写？

我们在需要输出日志信息的“每一人”类中做如下的三个工作： 
1、导入所有需的commongs-logging类： 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory;

如果愿意简化的话，还可以两行合为一行： 
import org.apache.commons.logging.*;  

2、在自己的类中定义一个org.apache.commons.logging.Log类的私有静态类成员： 
private static Log log = LogFactory.getLog(YouClassName.class);

注意这里定义的是static成员，以避免产生多个实例。

LogFactory.getLog()方法的参数使用的是当前类的class，这是目前被普通认为的最好的方式。为什么不写作LogFactory.getLog(this.getClass())？因为static类成
员访问不到this指针！

3、使用org.apache.commons.logging.Log类的成员方法输出日志信息： 
log.debug("111"); 
log.info("222"); 
log.warn("333"); 
log.error("444"); 
log.fatal("555");

这里的log，就是上面第二步中定义的类成员变量，其类型是org.apache.commons.logging.Log，通过该类的成员方法，我们就可以将不同性质的日志信息输出到目的地（目的地
是哪里？视配置可定，可能是stdout，也可能是文件，还可能是发送到邮件，甚至发送短信到手机……详见下文对log4j.properties的介绍）： 
 debug()   输出“调试”级别的日志信息； 
 info()    输出“信息”级别的日志信息； 
 warn()    输出“警告”级别的日志信息； 
 error()   输出“错误”级别的日志信息；
 fatal()   输出“致命错误”级别的日志信息；

根据不同的性质，日志信息通常被分成不同的级别，从低到高依次是：“调试（DEBUG）”“信息（INFO）”“警告（WARN）”“错误（ERROR）”“致命错误（FATAL）”。为什么要把日志
信息分成不同的级别呢？这实际上是方便我们更好的控制它。比如，通过Log4j的配置文件，我们可以设置“输出‘调试’及以上级别的日志信息”（即“调试”“信息”“警告”“错误”“致命
错误”），这对项目开发人员可能是有用的；我们还可以设置“输出“警告”及以上级别的日志信息”（即“警告”“错误”“致命错误”），这对项目最终用户可能是有用的。 
   仅从字面上理解，也可以大致得出结论：最常用的应该是debug()和info()；而warn()、error()、fatal()仅在相应事件发生后才使用。  

从上面三个步骤可以看出，使用commons-logging的日志接口非常的简单，不需要记忆太多东西：仅仅用到了两个类Log, LogFactory，并且两个类的方法都非常少（后者只用到
一个方法，前者经常用到的也只是上面第三步中列出的几个），同时参数又非常简单。

上面所介绍的方法是目前被普通应用的，可以说是被标准化了的方法，几乎所有的人都是这么用。如果不信，或想确认一下，就去下载几个知名的Java开源项目源代码看一下吧。  

下面给出一个完整的Java类的代码： 
package liigo.testlog; 
import org.apache.commons.logging.Log; 
import org.apache.commons.logging.LogFactory; 

public class TestLog { 
    private static Log log = LogFactory.getLog(TestLog.class); 
    public void test()     { 
        log.debug("111"); 
        log.info("222"); 
        log.warn("333"); 
        log.error("444"); 
        log.fatal("555"); 
    }  

    public static void main(String[] args)     { 
        TestLog testLog = new TestLog(); 
        testLog.test(); 
    } 
}  

只要保证commons-logging的jar包在classpath中，上述代码肯定可以很顺利的编译通过。那它的执行结果是怎么样的呢？恐怕会有很大的不同，请继续往下看。  

Log4j在哪里呢？它发挥作用了吗？

应该注意到，我们上面给出的源代码，完全没有涉及到Log4j——这正是我们所希望的，这也正是commons-logging所要达到的目标之一。

可是，怎么才能让Log4j发挥它的作用呢？答案很简单，只需满足“classpath中有Log4j的jar包”。前面已经说过了，commons-logging会自动发现并应用Log4j。所以只要它
存在，它就发挥作用。（它不存在呢？自然就不发挥作用，commons-logging会另行选择其它的日志实现类。）

注意：配置文件log4j.properties对Log4j来说是必须的。如果classpath中没有该配置文件，或者配置不对，将会引发运行时异常。

这样，要正确地应用Log4j输出日志信息，log4j.properties的作用就很重要了。好在该文件有通用的模板，复制一份（稍加修改）就可以使用。几乎每一个Java项目目录内都会
有一个log4j.properties文件，可下载几个Java开源项目源代码查看。本文最后也附一个模板性质的log4j.properties文件，直接复制过去就可以用，或者根据自己的需要
稍加修改。后文将会log4j.properties文件适当作一些介绍。

关于Log4j比较全面的配置
LOG4J的配置之简单使它遍及于越来越多的应用中了：Log4J配置文件实现了输出到控制台、文件、回滚文件、发送日志邮件、输出到数据库日志表、自定义标签等全套功能。择其一二
使用就够用了

log4j.rootLogger=DEBUG,CONSOLE,A1,im 
log4j.addivity.org.apache=true  

# 应用于控制台 
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 
log4j.appender.Threshold=DEBUG 
log4j.appender.CONSOLE.Target=System.out 
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n 

#应用于文件 
log4j.appender.FILE=org.apache.log4j.FileAppender 
log4j.appender.FILE.File=file.log 
log4j.appender.FILE.Append=false 
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
# Use this layout for LogFactor 5 analysis 

# 应用于文件回滚 
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender 
log4j.appender.ROLLING_FILE.Threshold=ERROR 
log4j.appender.ROLLING_FILE.File=rolling.log 
log4j.appender.ROLLING_FILE.Append=true 
log4j.appender.ROLLING_FILE.MaxFileSize=10KB 
log4j.appender.ROLLING_FILE.MaxBackupIndex=1 
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 

#应用于socket 
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender 
log4j.appender.SOCKET.RemoteHost=localhost 
log4j.appender.SOCKET.Port=5001 
log4j.appender.SOCKET.LocationInfo=true 
# Set up for Log Facter 5 
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout 
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n 

# Log Factor 5 Appender 
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender 
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000 

# 发送日志给邮件 
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender 
log4j.appender.MAIL.Threshold=FATAL 
log4j.appender.MAIL.BufferSize=10 
log4j.appender.MAIL.From=web@www.wuset.com 
log4j.appender.MAIL.SMTPHost=www.wusetu.com 
log4j.appender.MAIL.Subject=Log4J Message 
log4j.appender.MAIL.To=web@www.wusetu.com 
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout 
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 

# 用于数据库 
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender 
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test 
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver 
log4j.appender.DATABASE.user=root 
log4j.appender.DATABASE.password= 
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n') 
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout 
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 

log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.A1.File=SampleMessages.log4j 
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j' 
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout 

#自定义Appender 
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender 

log4j.appender.im.host = mail.cybercorlin.net 
log4j.appender.im.username = username 
log4j.appender.im.password = password 
log4j.appender.im.recipient = corlin@cybercorlin.net 

log4j.appender.im.layout=org.apache.log4j.PatternLayout 
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n第二部分：

【stone 的 log4j配置详解】
Log4J的配置文件(Configuration File)就是用来设置记录器的级别、存放器和布局的，它可接key=value格式的设置或xml格式的设置信息。通过配置，可以创建出Log4J的运
行环境。
1. 配置文件Log4J配置文件的基本格式如下： 

#配置根Logger：
log4j.rootLogger = [level],appenderName1,appenderName2,...

#配置日志信息输出目的地Appender
log4j.appender.appenderName=fully.qualified.name.of.appender.class
log4j.appender.appenderName.option1=value1
	...
log4j.appender.appenderName.optionN=valueN 

#配置日志信息的格式（布局）
log4j.appender.appenderName.layout=fully.qualified.name.of.layout.class
log4j.appender.appenderName.layout.option1=value1
	...
log4j.appender.appenderName.layout.optionN=valueN  

其中【level】是日志输出级别，共有5级：
FATAL      0  
ERROR      3  
WARN       4  
INFO       6  
DEBUG      7  

Appender 为日志输出目的地，Log4j提供的appender有以下几种：
org.apache.log4j.ConsoleAppender（控制台），
org.apache.log4j.FileAppender（文件），
org.apache.log4j.DailyRollingFileAppender（每天产生一个日志文件），
org.apache.log4j.RollingFileAppender（文件大小到达指定尺寸的时候产生一个新的文件），
org.apache.log4j.WriterAppender（将日志信息以流格式发送到任意指定的地方） 

Layout：日志输出格式，Log4j提供的layout有以下几种：
org.apache.log4j.HTMLLayout（以HTML表格形式布局），
org.apache.log4j.PatternLayout（可以灵活地指定布局模式），
org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），
org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息） 

打印参数: Log4J采用类似C语言中的printf函数的打印格式格式化日志信息，如下:
%m   输出代码中指定的消息　　
%p 输出优先级，即DEBUG，INFO，WARN，ERROR，FATAL 　　
%r 输出自应用启动到输出该log信息耗费的毫秒数 　　
%c 输出所属的类目，通常就是所在类的全名 　　
%t 输出产生该日志事件的线程名 　　
%n 输出一个回车换行符，Windows平台为“\r\n”，Unix平台为“\n” 
%d 输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy MMM dd HH:mm:ss , SSS}，输出类似：2002年10月18日  22 ： 10 ： 28 ， 921  　　
%l 输出日志事件的发生位置，包括类目名、发生的线程，以及在代码中的行数。举例：Testlog4.main(TestLog4.java: 10 )  

2. 在代码中初始化Logger: 
1）在程序中调用BasicConfigurator.configure()方法：给根记录器增加一个ConsoleAppender，输出格式通过PatternLayout设为"%-4r [%t] %-5p %c %x - %m%n"，还有根记录器的默认级别是Level.DEBUG. 
2）配置放在文件里，通过命令行参数传递文件名字，通过PropertyConfigurator.configure(args[x])解析并配置；
3）配置放在文件里，通过环境变量传递文件名等信息，利用log4j默认的初始化过程解析并配置；
4）配置放在文件里，通过应用服务器配置传递文件名等信息，利用一个特殊的servlet来完成配置。

3. 为不同的 Appender 设置日志输出级别：当调试系统时，我们往往注意的只是异常级别的日志输出，但是通常所有级别的输出都是放在一个文件里的，如果日志输出的级别是BUG！？那就慢慢去找吧。这时我们也许会想要是能把异常信息单独输出到一个文件里该多好啊。当然可以，Log4j已经提供了这样的功能，我们只需要在配置中修改Appender的Threshold 就能实现,比如下面的例子：
[配置文件]
 ### set log levels ###
 log4j.rootLogger = debug ,  stdout ,  D ,  E
 
 ### 输出到控制台 ###
 log4j.appender.stdout = org.apache.log4j.ConsoleAppender
 log4j.appender.stdout.Target = System.out
 log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
 log4j.appender.stdout.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{ 1 }:%L - %m%n
 
 ### 输出到日志文件 ###
 log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
 log4j.appender.D.File = logs/log.log
 log4j.appender.D.Append = true
 log4j.appender.D.Threshold = DEBUG ## 输出DEBUG级别以上的日志
 log4j.appender.D.layout = org.apache.log4j.PatternLayout
 log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
 
 ### 保存异常信息到单独文件 ###
 log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
 log4j.appender.D.File = logs/error.log ## 异常日志文件名
 log4j.appender.D.Append = true
 log4j.appender.D.Threshold = ERROR ## 只输出ERROR级别以上的日志!!!
 log4j.appender.D.layout = org.apache.log4j.PatternLayout
 log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n 

[代码中使用] 
public   class  TestLog4j  {     
	public   static   void  main(String[] args) {        
	   PropertyConfigurator.configure( " D:/Code/conf/log4j.properties " );
	   Logger logger  =  Logger.getLogger(TestLog4j. class );
	   logger.debug( " debug " );
	   logger.error( " error " );
	} 
} 
运行一下，看看异常信息是不是保存在了一个单独的文件error.log中

log4j.properties 使用

一.参数意义说明

输出级别的种类
ERROR、WARN、INFO、DEBUG
ERROR 为严重错误 主要是程序的错误
WARN 为一般警告，比如session丢失
INFO 为一般要显示的信息，比如登录登出
DEBUG 为程序的调试信息

配置日志信息输出目的地
log4j.appender.appenderName = fully.qualified.name.of.appender.class
1.org.apache.log4j.ConsoleAppender（控制台）
2.org.apache.log4j.FileAppender（文件）
3.org.apache.log4j.DailyRollingFileAppender（每天产生一个日志文件）
4.org.apache.log4j.RollingFileAppender（文件大小到达指定尺寸的时候产生一个新的文件）
5.org.apache.log4j.WriterAppender（将日志信息以流格式发送到任意指定的地方）

配置日志信息的格式
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
1.org.apache.log4j.HTMLLayout（以HTML表格形式布局），
2.org.apache.log4j.PatternLayout（可以灵活地指定布局模式），
3.org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），
4.org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息）

控制台选项
Threshold=DEBUG:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
Target=System.err：默认情况下是：System.out,指定输出控制台

FileAppender选项
Threshold=DEBUF:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
File=mylog.txt:指定消息输出到mylog.txt文件。
Append=false:默认值是true,即将消息增加到指定文件中，false指将消息覆盖指定的文件内容。

RollingFileAppender选项
Threshold=DEBUG:指定日志消息的输出最低层次。
ImmediateFlush=true:默认值是true,意谓着所有的消息都会被立即输出。
File=mylog.txt:指定消息输出到mylog.txt文件。
Append=false:默认值是true,即将消息增加到指定文件中，false指将消息覆盖指定的文件内容。
MaxFileSize=100KB: 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时，将会自动滚动，即将原来的内容移到mylog.log.1文件。
MaxBackupIndex=2:指定可以产生的滚动文件的最大数。
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n

日志信息格式中几个符号所代表的含义： 
-X号: X信息输出时左对齐；
%p: 输出日志信息优先级，即DEBUG，INFO，WARN，ERROR，FATAL, 
%d: 输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy MMM dd HH:mm:ss,SSS}，输出类似：2002年10月18日 22：10：28，921 
%r: 输出自应用启动到输出该log信息耗费的毫秒数
%c: 输出日志信息所属的类目，通常就是所在类的全名 
%t: 输出产生该日志事件的线程名 
%l: 输出日志事件的发生位置，相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程，以及在代码中的行数。举例：Testlog4.main (TestLog4.java:10) 
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
%%: 输出一个"%"字符 %F: 输出日志消息产生时所在的文件名称
%L: 输出代码中的行号
%m: 输出代码中指定的消息,产生的日志具体信息 
%n: 输出一个回车换行符，Windows平台为"\r\n"，Unix平台为"\n"输出日志信息换行 
可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。如： 
1)%20c：指定输出category的名称，最小的宽度是20，如果category的名称小于20的话，默认的情况下右对齐。
2)%-20c:指定输出category的名称，最小的宽度是20，如果category的名称小于20的话，"-"号指定左对齐。 
3)%.30c:指定输出category的名称，最大的宽度是30，如果category的名称大于30的话，就会将左边多出的字符截掉，但小于30的话也不会有空格。
4)%20.30c:如果category的名称小于20就补空格，并且右对齐，如果其名称长于30字符，就从左边较远输出的字符截掉。

二.文件配置Sample1
log4j.rootLogger=DEBUG,A1,R
#log4j.rootLogger=INFO,A1,R

# ConsoleAppender 输出
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n

# File 输出 一天一个文件,输出路径可以定制,一般在根路径下
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=blog_log.txt
log4j.appender.R.MaxFileSize=500KB
log4j.appender.R.MaxBackupIndex=10
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c] [%p] - %m%n

文件配置Sample2
下面给出的Log4J配置文件实现了输出到控制台，文件，回滚文件，发送日志邮件，输出到数据库日志表，自定义标签等全套功能。
log4j.rootLogger=DEBUG,CONSOLE,A1,im 
#DEBUG,CONSOLE,FILE,ROLLING_FILE,MAIL,DATABASE
log4j.addivity.org.apache=true

# Console Appender
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 
log4j.appender.Threshold=DEBUG 
log4j.appender.CONSOLE.Target=System.out 
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]n%c[CATEGORY]%n%m[MESSAGE]%n%n

# File Appender
log4j.appender.FILE=org.apache.log4j.FileAppender 
log4j.appender.FILE.File=file.log 
log4j.appender.FILE.Append=false 
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
 # Use this layout for LogFactor 5 analysis

# Rolling File
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender 
log4j.appender.ROLLING_FILE.Threshold=ERROR 
log4j.appender.ROLLING_FILE.File=rolling.log 
log4j.appender.ROLLING_FILE.Append=true 
log4j.appender.ROLLING_FILE.MaxFileSize=10KB 
log4j.appender.ROLLING_FILE.MaxBackupIndex=1 
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
 
# Socket Appender
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender 
log4j.appender.SOCKET.RemoteHost=localhost 
log4j.appender.SOCKET.Port=5001 
log4j.appender.SOCKET.LocationInfo=true 
 
# Set up for Log Facter 5 
 log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout 
 log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n

# Log Factor 5 Appender 
 log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender 
 log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
 
 # SMTP Appender ####################### 
 log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender 
 log4j.appender.MAIL.Threshold=FATAL 
 log4j.appender.MAIL.BufferSize=10 
 log4j.appender.MAIL.From=chenyl@yeqiangwei.com
 log4j.appender.MAIL.SMTPHost=mail.hollycrm.com 
 log4j.appender.MAIL.Subject=Log4J Message 
 log4j.appender.MAIL.To=chenyl@yeqiangwei.com
 log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout 
 log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
 
# JDBC Appender ####################### 
 log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender 
 log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test 
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver 
log4j.appender.DATABASE.user=root 
log4j.appender.DATABASE.password= 
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n') 
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout 
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.A1.File=SampleMessages.log4j 
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j' 
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout

#自定义Appender ################### 
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net 
log4j.appender.im.username = username 
log4j.appender.im.password = password 
log4j.appender.im.recipient = corlin@yeqiangwei.com
log4j.appender.im.layout=org.apache.log4j.PatternLayout 
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

三.高级使用
实验目的： 
1.把FATAL级错误写入2000NT日志 
2. WARN，ERROR，FATAL级错误发送email通知管理员
3.其他级别的错误直接在后台输出
实验步骤： 
输出到2000NT日志 
1.把Log4j压缩包里的NTEventLogAppender.dll拷到WINNT\SYSTEM32目录下
2.写配置文件log4j.properties

 # 在2000系统日志输出 
 log4j.logger.NTlog=FATAL, A8 
 # APPENDER A8 
 log4j.appender.A8=org.apache.log4j.nt.NTEventLogAppender 
 log4j.appender.A8.Source=JavaTest 
 log4j.appender.A8.layout=org.apache.log4j.PatternLayout 
 log4j.appender.A8.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
3.调用代码： 
 Logger logger2 = Logger.getLogger("NTlog"); //要和配置文件中设置的名字相同 
 logger2.debug("debug!!!"); 
 logger2.info("info!!!"); 
 logger2.warn("warn!!!"); 
 logger2.error("error!!!"); 
 //只有这个错误才会写入2000日志 
 logger2.fatal("fatal!!!");

发送email通知管理员： 
1. 首先下载JavaMail和JAF,   
	http://java.sun.com/j2ee/ja/javamail/index.html  
	http://java.sun.com/beans/glasgow/jaf.html 
	在项目中引用mail.jar和activation.jar。 
2. 写配置文件
 # 将日志发送到email 
 log4j.logger.MailLog=WARN,A5 
 #  APPENDER A5 
 log4j.appender.A5=org.apache.log4j.net.SMTPAppender 
 log4j.appender.A5.BufferSize=5 
 log4j.appender.A5.To=chunjie@yeqiangwei.com 
 log4j.appender.A5.From=error@yeqiangwei.com 
 log4j.appender.A5.Subject=ErrorLog 
 log4j.appender.A5.SMTPHost=smtp.263.net 
 log4j.appender.A5.layout=org.apache.log4j.PatternLayout 
 log4j.appender.A5.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n 
3.调用代码：
 #把日志发送到mail 
 Logger logger3 = Logger.getLogger("MailLog"); 
 logger3.warn("warn!!!"); 
 logger3.error("error!!!"); 
 logger3.fatal("fatal!!!");

在后台输出所有类别的错误： 
1. 写配置文件
 # 在后台输出 
 log4j.logger.console=DEBUG, A1 
 # APPENDER A1 
 log4j.appender.A1=org.apache.log4j.ConsoleAppender 
 log4j.appender.A1.layout=org.apache.log4j.PatternLayout 
 log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n 
2．调用代码 
 Logger logger1 = Logger.getLogger("console"); 
 logger1.debug("debug!!!"); 
 logger1.info("info!!!"); 
 logger1.warn("warn!!!"); 
 logger1.error("error!!!"); 
 logger1.fatal("fatal!!!");
-------------------------------------------------------------------- 
全部配置文件：log4j.properties 
# 在后台输出 
log4j.logger.console=DEBUG, A1 
# APPENDER A1 
log4j.appender.A1=org.apache.log4j.ConsoleAppender 
log4j.appender.A1.layout=org.apache.log4j.PatternLayout 
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
# 在2000系统日志输出 
log4j.logger.NTlog=FATAL, A8 
# APPENDER A8 
log4j.appender.A8=org.apache.log4j.nt.NTEventLogAppender 
log4j.appender.A8.Source=JavaTest 
log4j.appender.A8.layout=org.apache.log4j.PatternLayout 
log4j.appender.A8.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
# 将日志发送到email 
log4j.logger.MailLog=WARN,A5 
#  APPENDER A5 
log4j.appender.A5=org.apache.log4j.net.SMTPAppender 
log4j.appender.A5.BufferSize=5 
log4j.appender.A5.To=chunjie@yeqiangwei.com 
log4j.appender.A5.From=error@yeqiangwei.com 
log4j.appender.A5.Subject=ErrorLog 
log4j.appender.A5.SMTPHost=smtp.263.net 
log4j.appender.A5.layout=org.apache.log4j.PatternLayout 
log4j.appender.A5.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
全部代码：Log4jTest.java  
//创建日期 2003-11-13   
//package edu.bcu.Bean;  
import org.apache.log4j.*;  
//import org.apache.log4j.nt.*;  
//import org.apache.log4j.net.*;  
public class Log4jTest  {
	public static void main(String args[]){
		PropertyConfigurator.configure("log4j.properties");
		//在后台输出    
		Logger logger1 = Logger.getLogger("console");    
		logger1.debug("debug!!!");    
		logger1.info("info!!!");    
		logger1.warn("warn!!!");    
		logger1.error("error!!!");    
		logger1.fatal("fatal!!!");//在NT系统日志输出    
		Logger logger2 = Logger.getLogger("NTlog");    
		//NTEventLogAppender nla = new NTEventLogAppender();    
		logger2.debug("debug!!!");    
		logger2.info("info!!!");    
		logger2.warn("warn!!!");    
		logger2.error("error!!!");    
		//只有这个错误才会写入2000日志    
		logger2.fatal("fatal!!!");
		//把日志发送到mail    
		Logger logger3 = Logger.getLogger("MailLog");    
		//SMTPAppender sa = new SMTPAppender();    
		logger3.warn("warn!!!");    
		logger3.error("error!!!");    
		logger3.fatal("fatal!!!");
		}  
	}
}
*/
/*
【使用commons-logging和Log4j】
什么要用日志（Log）?
这个……就不必说了吧。
为什么不用System.out.println()?
功能太弱；不易于控制。如果暂时不想输出了怎么办？如果想输出到文件怎么办？如果想部分输出怎么办？……

为什么同时使用commons-logging和Log4j?为什么不仅使用其中之一？
Commons-loggin的目的是为“所有的Java日志实现”提供一个统一的接口，它自身的日志功能平常弱（只有一个简单的SimpleLog?），所以一般不会单独使用它。

	Log4j的功能非常全面强大，是目前的首选。我发现几乎所有的Java开源项目都会用到Log4j，但我同时发现，所有用到Log4j的项目一般也同时会用到commons-loggin。我想，
大家都不希望自己的项目与Log4j绑定的太紧密吧。另外一个我能想到的“同时使用commons-logging和Log4j”的原因是，简化使用和配置。

   强调一点，“同时使用commons-logging和Log4j”，与“单独使用Log4j”相比，并不会带来更大的学习、配置和维护成本，反而更加简化了我们的工作。我想这也是为什么“所
有用到Log4j的项目一般也同时会用到commons-loggin”的原因之一吧。

Commons-logging能帮我们做什么？
● 提供一个统一的日志接口，简单了操作，同时避免项目与某个日志实现系统紧密a耦合
● 很贴心的帮我们自动选择适当的日志实现系统（这一点非常好！）
● 它甚至不需要配置

这里看一下它怎么“‘很贴心的’帮我们‘自动选择’‘适当的’日志实现系统”：
1) 首先在classpath下寻找自己的配置文件commons-logging.properties，如果找到，则使用其中定义的Log实现类；
2) 如果找不到commons-logging.properties文件，则在查找是否已定义系统环境变量org.apache.commons.logging.Log，找到则使用其定义的Log实现类；
3) 否则，查看classpath中是否有Log4j的包，如果发现，则自动使用Log4j作为日志实现类；
4) 否则，使用JDK自身的日志实现类（JDK1.4以后才有日志实现类）；
5) 否则，使用commons-logging自己提供的一个简单的日志实现类SimpleLog；
（以上顺序不保证完全准确，请参考官方文档）

可见，commons-logging总是能找到一个日志实现类，并且尽可能找到一个“最合适”的日志实现类。我说它“很贴心”实际上是因为：
1、可以不需要配置文件；
2、自动判断有没有Log4j包，有则自动使用之；
3、最悲观的情况下也总能保证提供一个日志实现（SimpleLog）。 
  可以看到，commons-logging对编程者和Log4j都非常友好。

  为了简化配置commons-logging，一般不使用commons-logging的配置文件，也不设置与commons-logging相关的系统环境变量，而只需将Log4j的Jar包放置
到classpash中就可以了。这样就很简单地完成了commons-logging与Log4j的融合。如果不想用Log4j了怎么办？只需将classpath中的Log4j的Jar包删除即可。

就这么简单！

代码应该怎么写？

我们在需要输出日志信息的“每一人”类中做如下的三个工作：
1、导入所有需的commongs-logging类：
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

如果愿意简化的话，还可以两行合为一行：
import org.apache.commons.logging.*;  

2、在自己的类中定义一个org.apache.commons.logging.Log类的私有静态类成员：
private static Log log = LogFactory.getLog(YouClassName.class);

注意这里定义的是static成员，以避免产生多个实例。

LogFactory.getLog()方法的参数使用的是当前类的class，这是目前被普通认为的最好的方式。为什么不写作LogFactory.getLog(this.getClass())？
因为static类成员访问不到this指针！

3、使用org.apache.commons.logging.Log类的成员方法输出日志信息：
log.debug("111");
log.info("222");
log.warn("333");
log.error("444");
log.fatal("555");

这里的log，就是上面第二步中定义的类成员变量，其类型是org.apache.commons.logging.Log，通过该类的成员方法，我们就可以将不同性质的日志信息输出到目的
地（目的地是哪里？视配置可定，可能是stdout，也可能是文件，还可能是发送到邮件，甚至发送短信到手机……详见下文对log4j.properties的介绍）：
● debug()   输出“调试”级别的日志信息；
● info()    输出“信息”级别的日志信息；
● warn()    输出“警告”级别的日志信息；
● error()   输出“错误”级别的日志信息；
● fatal()   输出“致命错误”级别的日志信息；

根据不同的性质，日志信息通常被分成不同的级别，从低到高依次是：“调试（DEBUG）”“信息（INFO）”“警告（WARN）”“错误（ERROR）”“致命错误（FATAL）”。为什么
要把日志信息分成不同的级别呢？这实际上是方便我们更好的控制它。比如，通过Log4j的配置文件，我们可以设置“输出‘调试’及以上级别的日志信息”（即“调试”“信息”
“警告”“错误”“致命错误”），这对项目开发人员可能是有用的；我们还可以设置“输出“警告”及以上级别的日志信息”（即“警告”“错误”“致命错误”），这对项目最终用户可能
是有用的。 
  仅从字面上理解，也可以大致得出结论：最常用的应该是debug()和info()；而warn()、error()、fatal()仅在相应事件发生后才使用。  

  从上面三个步骤可以看出，使用commons-logging的日志接口非常的简单，不需要记忆太多东西：仅仅用到了两个类Log, LogFactory，并且两个类的方法都非常少（后
者只用到一个方法，前者经常用到的也只是上面第三步中列出的几个），同时参数又非常简单。

上面所介绍的方法是目前被普通应用的，可以说是被标准化了的方法，几乎所有的人都是这么用。如果不信，或想确认一下，就去下载几个知名的Java开源项目源代码看一下吧。  

下面给出一个完整的Java类的代码： 
package liigo.testlog; 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; 

public class TestLog { 
    private static Log log = LogFactory.getLog(TestLog.class); 
    public void test()     { 
        log.debug("111"); 
        log.info("222"); 
        log.warn("333"); 
        log.error("444"); 
        log.fatal("555"); 
    }  

    public static void main(String[] args)     { 
        TestLog testLog = new TestLog(); 
        testLog.test(); 
    }
}  

只要保证commons-logging的jar包在classpath中，上述代码肯定可以很顺利的编译通过。那它的执行结果是怎么样的呢？恐怕会有很大的不同，请继续往下看。  

Log4j在哪里呢？它发挥作用了吗？

应该注意到，我们上面给出的源代码，完全没有涉及到Log4j——这正是我们所希望的，这也正是commons-logging所要达到的目标之一。

可是，怎么才能让Log4j发挥它的作用呢？答案很简单，只需满足“classpath中有Log4j的jar包”。前面已经说过了，commons-logging会自动发现并应用Log4j。所以只要它
存在，它就发挥作用。（它不存在呢？自然就不发挥作用，commons-logging会另行选择其它的日志实现类。）

注意：配置文件log4j.properties对Log4j来说是必须的。如果classpath中没有该配置文件，或者配置不对，将会引发运行时异常。

  这样，要正确地应用Log4j输出日志信息，log4j.properties的作用就很重要了。好在该文件有通用的模板，复制一份（稍加修改）就可以使用。几乎每一个Java项目目录内都
会有一个log4j.properties文件，可下载几个Java开源项目源代码查看。本文最后也附一个模板性质的log4j.properties文件，直接复制过去就可以用，或者根据自己的需要
稍加修改。后文将会log4j.properties文件适当作一些介绍。

关于Log4j比较全面的配置
LOG4J的配置之简单使它遍及于越来越多的应用中了：Log4J配置文件实现了输出到控制台、文件、回滚文件、发送日志邮件、输出到数据库日志表、自定义标签等全套功能。择其一二使用就够用了

log4j.rootLogger=DEBUG,CONSOLE,A1,im
log4j.addivity.org.apache=true  

additivity的作用在于 children-logger是否使用 rootLogger的配置，例如 输出终端。
它是 子Logger 是否继承 父Logger 的 输出源（appender） 的标志位。具体说，默认情况下子Logger会继承父Logger的appender，也就是说子Logger会在父Logger
的appender里输出。若是additivity设为false，则子Logger只会在自己的appender里输出，而不会在父Logger的appender里输出。
使用例子：下面是一个log4j的配置文件，父logger是console与R，子logger是log4j.logger.mobileLogger

log4j.rootLogger=DEBUG,console,R

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%-5p %d [%t] %c: %m%n


log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=/export/home/tomcat/mobile/tomcatLogs/tomcat.log
log4j.appender.R.DatePattern='.'yyyy-MM-dd
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%-5p %d [%t] %c: %m%n

log4j.logger.mobileLogger=TRACE,mobileLogger
log4j.additivity.mobileLogger=false
log4j.appender.mobileLogger=org.apache.log4j.DailyRollingFileAppender
log4j.appender.mobileLogger.layout=org.apache.log4j.PatternLayout
log4j.appender.mobileLogger.DatePattern='.'yyyy-MM-dd-HH-mm
log4j.appender.mobileLogger.layout.ConversionPattern=%m%n
log4j.appender.mobileLogger.file=/export/home/tomcat/mobile/mobileLogs/mobile.log
log4j.appender.mobileLogger.encoding=UTF-8
*/

/*
# 应用于控制台
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n

#应用于文件
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis


# 应用于文件回滚
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

#应用于socket
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n


# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000

# 发送日志给邮件
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


# 用于数据库
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout

#自定义Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender

log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net

log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

*/